package com.djf.djfpgsql.wrapper.controller;

import com.djf.djfpgsql.entity.User;
import com.djf.djfpgsql.wrapper.service.UserWrapperService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 纯Wrapper方式的Controller层
 * 展示MyBatis-Plus Wrapper在Web层的应用
 * 提供RESTful API接口，处理MySQL和PostgreSQL的差异
 */
@RestController
@RequestMapping("/api/wrapper/users")
public class UserWrapperController {

    @Autowired
    private UserWrapperService userWrapperService;

    // ==================== 基础CRUD操作（完全兼容） ====================
    
    /**
     * 获取所有用户
     * GET /api/wrapper/users
     */
    @GetMapping
    public List<User> getAllUsers() {
        return userWrapperService.getAllUsers();
    }
    
    /**
     * 根据ID获取用户
     * GET /api/wrapper/users/{id}
     */
    @GetMapping("/{id}")
    public User getUserById(@PathVariable Long id) {
        return userWrapperService.getUserById(id);
    }
    
    /**
     * 创建用户
     * POST /api/wrapper/users
     */
    @PostMapping
    public Map<String, Object> createUser(@RequestBody User user) {
        Map<String, Object> result = new HashMap<>();
        boolean success = userWrapperService.saveUser(user);
        result.put("success", success);
        result.put("message", success ? "用户创建成功" : "用户创建失败");
        result.put("user", user);
        return result;
    }
    
    /**
     * 更新用户
     * PUT /api/wrapper/users/{id}
     */
    @PutMapping("/{id}")
    public Map<String, Object> updateUser(@PathVariable Long id, @RequestBody User user) {
        Map<String, Object> result = new HashMap<>();
        user.setId(id);
        boolean success = userWrapperService.updateUser(user);
        result.put("success", success);
        result.put("message", success ? "用户更新成功" : "用户更新失败");
        return result;
    }
    
    /**
     * 删除用户
     * DELETE /api/wrapper/users/{id}
     */
    @DeleteMapping("/{id}")
    public Map<String, Object> deleteUser(@PathVariable Long id) {
        Map<String, Object> result = new HashMap<>();
        boolean success = userWrapperService.deleteUser(id);
        result.put("success", success);
        result.put("message", success ? "用户删除成功" : "用户删除失败");
        return result;
    }

    // ==================== 条件查询（完全兼容） ====================
    
    /**
     * 根据年龄范围查询用户
     * GET /api/wrapper/users/age-range?minAge=18&maxAge=65
     */
    @GetMapping("/age-range")
    public List<User> getUsersByAgeRange(
            @RequestParam(required = false) Integer minAge,
            @RequestParam(required = false) Integer maxAge) {
        return userWrapperService.getUsersByAgeRange(minAge, maxAge);
    }
    
    /**
     * 根据余额范围查询用户
     * GET /api/wrapper/users/balance-range?minBalance=1000&maxBalance=10000
     */
    @GetMapping("/balance-range")
    public List<User> getUsersByBalanceRange(
            @RequestParam Double minBalance,
            @RequestParam Double maxBalance) {
        return userWrapperService.getUsersByBalanceRange(minBalance, maxBalance);
    }
    
    /**
     * 根据活跃状态查询用户
     * GET /api/wrapper/users/active?status=true
     */
    @GetMapping("/active")
    public List<User> getUsersByActiveStatus(@RequestParam Boolean status) {
        return userWrapperService.getUsersByActiveStatus(status);
    }
    
    /**
     * 根据邮箱域名查询用户
     * GET /api/wrapper/users/email-domain?domain=gmail.com
     */
    @GetMapping("/email-domain")
    public List<User> getUsersByEmailDomain(@RequestParam String domain) {
        return userWrapperService.getUsersByEmailDomain(domain);
    }

    // ==================== 数据库特定的字符串查询 ====================
    
    /**
     * 字符串模糊搜索 - MySQL版本
     * GET /api/wrapper/users/search/mysql?name=张
     */
    @GetMapping("/search/mysql")
    public Map<String, Object> searchUsersByNameMySQL(@RequestParam String name) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.searchUsersByNameMySQL(name);
        result.put("users", users);
        result.put("database", "MySQL");
        result.put("search_type", "LIKE + CONCAT (区分大小写)");
        result.put("count", users.size());
        return result;
    }
    
    /**
     * 字符串模糊搜索 - PostgreSQL版本
     * GET /api/wrapper/users/search/pgsql?name=张
     */
    @GetMapping("/search/pgsql")
    public Map<String, Object> searchUsersByNamePGSQL(@RequestParam String name) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.searchUsersByNamePGSQL(name);
        result.put("users", users);
        result.put("database", "PostgreSQL");
        result.put("search_type", "ILIKE + || (不区分大小写)");
        result.put("count", users.size());
        return result;
    }
    
    /**
     * 多字段模糊搜索 - MySQL版本
     * GET /api/wrapper/users/search-multi/mysql?keyword=张
     */
    @GetMapping("/search-multi/mysql")
    public Map<String, Object> searchUsersMultiFieldMySQL(@RequestParam String keyword) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.searchUsersMultiFieldMySQL(keyword);
        result.put("users", users);
        result.put("database", "MySQL");
        result.put("search_fields", "name, email");
        result.put("search_type", "LIKE + CONCAT");
        result.put("count", users.size());
        return result;
    }
    
    /**
     * 多字段模糊搜索 - PostgreSQL版本
     * GET /api/wrapper/users/search-multi/pgsql?keyword=张
     */
    @GetMapping("/search-multi/pgsql")
    public Map<String, Object> searchUsersMultiFieldPGSQL(@RequestParam String keyword) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.searchUsersMultiFieldPGSQL(keyword);
        result.put("users", users);
        result.put("database", "PostgreSQL");
        result.put("search_fields", "name, email");
        result.put("search_type", "ILIKE + ||");
        result.put("count", users.size());
        return result;
    }

    // ==================== 数据库特定的日期查询 ====================
    
    /**
     * 日期范围查询 - MySQL版本
     * GET /api/wrapper/users/recent/mysql?days=30
     */
    @GetMapping("/recent/mysql")
    public Map<String, Object> getRecentUsersMySQL(@RequestParam int days) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.getRecentUsersMySQL(days);
        result.put("users", users);
        result.put("database", "MySQL");
        result.put("date_function", "DATE_SUB(NOW(), INTERVAL ? DAY)");
        result.put("days", days);
        result.put("count", users.size());
        return result;
    }
    
    /**
     * 日期范围查询 - PostgreSQL版本
     * GET /api/wrapper/users/recent/pgsql?days=30
     */
    @GetMapping("/recent/pgsql")
    public Map<String, Object> getRecentUsersPGSQL(@RequestParam int days) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.getRecentUsersPGSQL(days);
        result.put("users", users);
        result.put("database", "PostgreSQL");
        result.put("date_function", "NOW() - INTERVAL '? days'");
        result.put("days", days);
        result.put("count", users.size());
        return result;
    }
    
    /**
     * 通用日期范围查询 - 推荐方式
     * GET /api/wrapper/users/recent?days=30
     */
    @GetMapping("/recent")
    public Map<String, Object> getRecentUsersUniversal(@RequestParam int days) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.getRecentUsersUniversal(days);
        result.put("users", users);
        result.put("database", "通用（推荐）");
        result.put("method", "Java LocalDateTime");
        result.put("days", days);
        result.put("count", users.size());
        return result;
    }
    
    /**
     * 按月份统计用户 - MySQL版本
     * GET /api/wrapper/users/stats/monthly/mysql
     */
    @GetMapping("/stats/monthly/mysql")
    public Map<String, Object> getUserCountByMonthMySQL() {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> stats = userWrapperService.getUserCountByMonthMySQL();
        result.put("statistics", stats);
        result.put("database", "MySQL");
        result.put("date_format", "DATE_FORMAT(created_at, '%Y-%m')");
        return result;
    }
    
    /**
     * 按月份统计用户 - PostgreSQL版本
     * GET /api/wrapper/users/stats/monthly/pgsql
     */
    @GetMapping("/stats/monthly/pgsql")
    public Map<String, Object> getUserCountByMonthPGSQL() {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> stats = userWrapperService.getUserCountByMonthPGSQL();
        result.put("statistics", stats);
        result.put("database", "PostgreSQL");
        result.put("date_format", "TO_CHAR(created_at, 'YYYY-MM')");
        return result;
    }

    // ==================== 数据库特定的JSON查询 ====================
    
    /**
     * JSON字段查询 - MySQL版本
     * GET /api/wrapper/users/city/mysql?city=北京
     */
    @GetMapping("/city/mysql")
    public Map<String, Object> getUsersByCityMySQL(@RequestParam String city) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.getUsersByCityMySQL(city);
        result.put("users", users);
        result.put("database", "MySQL");
        result.put("json_function", "JSON_EXTRACT(profile, '$.city')");
        result.put("city", city);
        result.put("count", users.size());
        return result;
    }
    
    /**
     * JSON字段查询 - PostgreSQL版本
     * GET /api/wrapper/users/city/pgsql?city=北京
     */
    @GetMapping("/city/pgsql")
    public Map<String, Object> getUsersByCityPGSQL(@RequestParam String city) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.getUsersByCityPGSQL(city);
        result.put("users", users);
        result.put("database", "PostgreSQL");
        result.put("json_operator", "profile->>'city'");
        result.put("city", city);
        result.put("count", users.size());
        return result;
    }
    
    /**
     * 复杂JSON查询 - MySQL版本
     * GET /api/wrapper/users/profile/mysql?city=北京&minAge=25
     */
    @GetMapping("/profile/mysql")
    public Map<String, Object> getUsersByProfileMySQL(
            @RequestParam(required = false) String city,
            @RequestParam(required = false) Integer minAge) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.getUsersByProfileMySQL(city, minAge);
        result.put("users", users);
        result.put("database", "MySQL");
        result.put("json_functions", "JSON_EXTRACT");
        result.put("filters", Map.of("city", city, "minAge", minAge));
        result.put("count", users.size());
        return result;
    }
    
    /**
     * 复杂JSON查询 - PostgreSQL版本
     * GET /api/wrapper/users/profile/pgsql?city=北京&minAge=25
     */
    @GetMapping("/profile/pgsql")
    public Map<String, Object> getUsersByProfilePGSQL(
            @RequestParam(required = false) String city,
            @RequestParam(required = false) Integer minAge) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.getUsersByProfilePGSQL(city, minAge);
        result.put("users", users);
        result.put("database", "PostgreSQL");
        result.put("json_operators", "->>, ::int");
        result.put("filters", Map.of("city", city, "minAge", minAge));
        result.put("count", users.size());
        return result;
    }

    // ==================== 统计和聚合查询 ====================
    
    /**
     * 用户统计 - MySQL版本
     * GET /api/wrapper/users/statistics/mysql
     */
    @GetMapping("/statistics/mysql")
    public Map<String, Object> getUserStatisticsMySQL() {
        return userWrapperService.getUserStatisticsMySQL();
    }
    
    /**
     * 用户统计 - PostgreSQL版本
     * GET /api/wrapper/users/statistics/pgsql
     */
    @GetMapping("/statistics/pgsql")
    public Map<String, Object> getUserStatisticsPGSQL() {
        return userWrapperService.getUserStatisticsPGSQL();
    }

    // ==================== 更新操作 ====================
    
    /**
     * 批量更新用户状态
     * PUT /api/wrapper/users/batch-status
     */
    @PutMapping("/batch-status")
    public Map<String, Object> batchUpdateUserStatus(
            @RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        @SuppressWarnings("unchecked")
        List<Long> userIds = (List<Long>) request.get("userIds");
        Boolean isActive = (Boolean) request.get("isActive");
        
        boolean success = userWrapperService.batchUpdateUserStatus(userIds, isActive);
        result.put("success", success);
        result.put("message", success ? "批量更新成功" : "批量更新失败");
        result.put("affected_users", userIds.size());
        return result;
    }
    
    /**
     * 更新最后登录时间 - MySQL版本
     * PUT /api/wrapper/users/{id}/last-login/mysql
     */
    @PutMapping("/{id}/last-login/mysql")
    public Map<String, Object> updateLastLoginMySQL(@PathVariable Long id) {
        Map<String, Object> result = new HashMap<>();
        boolean success = userWrapperService.updateLastLoginMySQL(id);
        result.put("success", success);
        result.put("database", "MySQL");
        result.put("timestamp_function", "NOW()");
        result.put("message", success ? "登录时间更新成功" : "登录时间更新失败");
        return result;
    }
    
    /**
     * 更新最后登录时间 - PostgreSQL版本
     * PUT /api/wrapper/users/{id}/last-login/pgsql
     */
    @PutMapping("/{id}/last-login/pgsql")
    public Map<String, Object> updateLastLoginPGSQL(@PathVariable Long id) {
        Map<String, Object> result = new HashMap<>();
        boolean success = userWrapperService.updateLastLoginPGSQL(id);
        result.put("success", success);
        result.put("database", "PostgreSQL");
        result.put("timestamp_function", "CURRENT_TIMESTAMP");
        result.put("message", success ? "登录时间更新成功" : "登录时间更新失败");
        return result;
    }
    
    /**
     * 通用更新最后登录时间 - 推荐方式
     * PUT /api/wrapper/users/{id}/last-login
     */
    @PutMapping("/{id}/last-login")
    public Map<String, Object> updateLastLoginUniversal(@PathVariable Long id) {
        Map<String, Object> result = new HashMap<>();
        boolean success = userWrapperService.updateLastLoginUniversal(id);
        result.put("success", success);
        result.put("method", "Java LocalDateTime（推荐）");
        result.put("message", success ? "登录时间更新成功" : "登录时间更新失败");
        return result;
    }
    
    /**
     * 更新用户余额
     * PUT /api/wrapper/users/{id}/balance
     */
    @PutMapping("/{id}/balance")
    public Map<String, Object> updateUserBalance(
            @PathVariable Long id,
            @RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        Double amount = Double.valueOf(request.get("amount").toString());
        String operation = (String) request.get("operation"); // add, subtract, set
        
        boolean success = userWrapperService.updateUserBalance(id, amount, operation);
        result.put("success", success);
        result.put("operation", operation);
        result.put("amount", amount);
        result.put("message", success ? "余额更新成功" : "余额更新失败");
        return result;
    }

    // ==================== 排序和分页 ====================
    
    /**
     * 获取排行榜用户
     * GET /api/wrapper/users/top?limit=10
     */
    @GetMapping("/top")
    public Map<String, Object> getTopUsersByBalance(@RequestParam(defaultValue = "10") int limit) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.getTopUsersByBalance(limit);
        result.put("users", users);
        result.put("limit", limit);
        result.put("sort_field", "balance");
        result.put("sort_order", "DESC");
        result.put("count", users.size());
        return result;
    }
    
    /**
     * 分页查询用户
     * GET /api/wrapper/users/page?page=1&size=10&sortField=created_at&sortOrder=desc
     */
    @GetMapping("/page")
    public Map<String, Object> getUsersWithPagination(
            @RequestParam(defaultValue = "1") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(defaultValue = "created_at") String sortField,
            @RequestParam(defaultValue = "desc") String sortOrder) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.getUsersWithPagination(page, size, sortField, sortOrder);
        result.put("users", users);
        result.put("page", page);
        result.put("size", size);
        result.put("sort_field", sortField);
        result.put("sort_order", sortOrder);
        result.put("count", users.size());
        return result;
    }

    // ==================== 复杂组合查询 ====================
    
    /**
     * 复杂条件查询
     * GET /api/wrapper/users/complex?namePattern=张&minAge=18&maxAge=65&minBalance=1000&isActive=true&emailDomain=gmail.com
     */
    @GetMapping("/complex")
    public Map<String, Object> getComplexQueryUsers(
            @RequestParam(required = false) String namePattern,
            @RequestParam(required = false) Integer minAge,
            @RequestParam(required = false) Integer maxAge,
            @RequestParam(required = false) Double minBalance,
            @RequestParam(required = false) Boolean isActive,
            @RequestParam(required = false) String emailDomain,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {
        
        Map<String, Object> result = new HashMap<>();
        
        LocalDateTime start = startDate != null ? LocalDateTime.parse(startDate) : null;
        LocalDateTime end = endDate != null ? LocalDateTime.parse(endDate) : null;
        
        List<User> users = userWrapperService.getComplexQueryUsers(
            namePattern, minAge, maxAge, minBalance, isActive, emailDomain, start, end);
        
        result.put("users", users);
        result.put("filters", Map.of(
            "namePattern", namePattern,
            "ageRange", minAge + "-" + maxAge,
            "minBalance", minBalance,
            "isActive", isActive,
            "emailDomain", emailDomain,
            "dateRange", startDate + " to " + endDate
        ));
        result.put("count", users.size());
        return result;
    }
    
    /**
     * 动态查询
     * POST /api/wrapper/users/dynamic
     */
    @PostMapping("/dynamic")
    public Map<String, Object> getDynamicQueryUsers(@RequestBody Map<String, Object> params) {
        Map<String, Object> result = new HashMap<>();
        List<User> users = userWrapperService.getDynamicQueryUsers(params);
        result.put("users", users);
        result.put("filters", params);
        result.put("count", users.size());
        return result;
    }

    // ==================== 信息和帮助接口 ====================
    
    /**
     * 获取Wrapper方式的功能对比信息
     * GET /api/wrapper/users/info
     */
    @GetMapping("/info")
    public Map<String, Object> getWrapperInfo() {
        Map<String, Object> info = new HashMap<>();
        
        // Wrapper方式的优势
        info.put("wrapper_advantages", List.of(
            "类型安全，编译时检查",
            "代码复用性强",
            "支持动态查询构建",
            "自动参数绑定和类型转换",
            "防SQL注入",
            "链式调用，可读性强",
            "统一的编码风格"
        ));
        
        // 数据库兼容性
        Map<String, Object> compatibility = new HashMap<>();
        compatibility.put("fully_compatible", List.of(
            "基础CRUD操作",
            "条件查询（eq, ne, gt, lt, ge, le, like, in等）",
            "排序和分组",
            "聚合函数（count, sum, avg等）",
            "分页查询",
            "批量操作"
        ));
        compatibility.put("need_special_handling", List.of(
            "字符串函数（CONCAT vs ||）",
            "日期函数（DATE_SUB vs INTERVAL）",
            "JSON操作（JSON_EXTRACT vs ->>）",
            "布尔值表示（1/0 vs true/false）",
            "全文搜索",
            "正则表达式",
            "窗口函数",
            "递归查询"
        ));
        info.put("database_compatibility", compatibility);
        
        // 最佳实践
        info.put("best_practices", List.of(
            "优先使用通用方法（Java类型）",
            "必要时使用apply()方法处理数据库特定语法",
            "使用@DS注解进行数据源切换",
            "复杂查询考虑使用自定义SQL",
            "合理使用缓存和分页",
            "注意性能优化"
        ));
        
        // API端点列表
        info.put("api_endpoints", Map.of(
            "basic_crud", "/api/wrapper/users (GET, POST, PUT, DELETE)",
            "search_mysql", "/api/wrapper/users/search/mysql",
            "search_pgsql", "/api/wrapper/users/search/pgsql",
            "recent_universal", "/api/wrapper/users/recent",
            "statistics", "/api/wrapper/users/statistics/{mysql|pgsql}",
            "complex_query", "/api/wrapper/users/complex",
            "dynamic_query", "/api/wrapper/users/dynamic"
        ));
        
        info.put("created_at", LocalDateTime.now());
        info.put("version", "1.0.0");
        info.put("description", "MyBatis-Plus Wrapper方式的完整示例");
        
        return info;
    }
}

/*
 * Wrapper方式Controller设计要点：
 * 
 * 1. 路径设计：
 *    - 基础路径：/api/wrapper/users
 *    - 数据库特定：/mysql, /pgsql
 *    - 功能分类：/search, /stats, /recent等
 * 
 * 2. 接口分类：
 *    - 通用接口：完全兼容MySQL和PostgreSQL
 *    - 特定接口：展示数据库差异处理
 *    - 推荐接口：最佳实践方案
 * 
 * 3. 响应格式：
 *    - 统一返回Map格式
 *    - 包含数据、元信息、统计信息
 *    - 标明使用的数据库和方法
 * 
 * 4. 参数处理：
 *    - 使用@RequestParam和@RequestBody
 *    - 支持可选参数
 *    - 类型自动转换
 * 
 * 5. 错误处理：
 *    - 返回success标志
 *    - 提供详细的错误信息
 *    - 记录操作日志
 * 
 * 6. 文档化：
 *    - 详细的注释说明
 *    - API使用示例
 *    - 功能对比信息
 */